#include "EventLoopThread.h"
#include "EventLoop.h"

EventLoopThread::EventLoopThread(const ThreadInitCallback &cb, 
        const std::string &name)
        : loop_(nullptr)
        , exiting_(false)
        , thread_(std::bind(&EventLoopThread::threadFunc, this), name)
        , mutex_()
        , cond_()
        , callback_(cb)
{

}

EventLoopThread::~EventLoopThread()
{
    exiting_ = true;
    if (loop_ != nullptr)
    {
        loop_->quit();
        thread_.join();
    }
}

// 启动线程并返回关联 EventLoop 对象
EventLoop* EventLoopThread::startLoop()
{
    thread_.start(); // 启动底层的新线程（执行threadFunc，创建新的EventLoop）

    /**
     *     因为这里启动了一个新线程,而执行threadFunc函数的线程不是这个新线程;所以需要loop_对象被赋值之后
     * 才能去唤醒条件变量,让新线程管理这个EventLoop对象; 
    */
    EventLoop *loop = nullptr;
    {
        std::unique_lock<std::mutex> lock(mutex_);
        while ( loop_ == nullptr ) // 等待 loop_ 被初始化
        {
            cond_.wait(lock);
        }
        loop = loop_;
    }
    return loop;
}

// 下面这个方法，实现在单独的新线程里面运行的
void EventLoopThread::threadFunc()
{
    EventLoop loop; // 创建一个独立的EventLoop，和上面的线程是一一对应的，one loop per thread

    if (callback_)
    {
        callback_(&loop);  // 如果设置了回调, 则先调用
    }

    {
        std::unique_lock<std::mutex> lock(mutex_);
        loop_ = &loop;
        cond_.notify_one(); // 通知 startLoop 方法继续执行
    }

    loop.loop(); // EventLoop loop  => Poller.poll
    std::unique_lock<std::mutex> lock(mutex_);
    loop_ = nullptr;
}
